using System;
using System.Drawing.Text;
using System.Drawing;
using System.Windows.Forms;

namespace EForms
{
	public class MenuItem : System.Windows.Forms.MenuItem
	{
		// config
		Color bgcolor  = SystemColors.ControlLightLight;
		Color ibgcolor = SystemColors.ControlLight; //Color.FromArgb(202, 202, 202);
		
		const int TEXTSTART = 24;
		//
		
		string shortcuttext = "";
		StringFormat stringformat = new StringFormat();
		Bitmap icon = null;
		int shortcuttextwidth;
		
		public MenuItem()
		{
			OwnerDraw = true;
		}
		
		public MenuItem(string name, EventHandler handler, Shortcut shortcut) : this(name, handler)
		{
			OwnerDraw = true;
			Shortcut = shortcut;
		}
		
		public MenuItem(string name, Icon icon) : base(name)
		{
			Icon = icon.ToBitmap();
			OwnerDraw = true;
		}
		
		public MenuItem(string name, Icon icon, EventHandler handler) : base(name, handler)
		{
			Icon = icon.ToBitmap();
			OwnerDraw = true;
		}
		
		public MenuItem(string name, Bitmap icon, EventHandler handler) : base(name, handler)
		{
			Icon = icon;
			OwnerDraw = true;
		}
		
		public MenuItem(string name, EventHandler handler) : base(name, handler)
		{
			OwnerDraw = true;
		}
		
		public MenuItem(string name) : base(name)
		{
			OwnerDraw = true;
		}
		
		public MenuItem(string name, Bitmap icon) : base(name)
		{
			Icon = icon;
			OwnerDraw = true;
		}
		
		public MenuItem(string name, MenuItem[] items) : base(name, items)
		{
			OwnerDraw = true;
		}
		
		public string ShortcutText {
			get {
				return shortcuttext;
			}
			set {
				shortcuttext = value;
			}
		}
		
		public Bitmap Icon {
			get {
				return icon;
			}
			set {
				icon = value;
			}
		}
		
		protected override void OnMeasureItem(MeasureItemEventArgs e)
		{
			base.OnMeasureItem(e);
			
			if (Shortcut != Shortcut.None) {
				Keys k = (Keys)Shortcut; 
				shortcuttext = System.ComponentModel.TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString(k); 
			}
			
			if (Text == "-") {
				e.ItemHeight = 8;
				e.ItemWidth  = 4;
				return;
			}

			int textwidth = (int)(e.Graphics.MeasureString(Text, SystemInformation.MenuFont).Width);
			shortcuttextwidth = (int)(e.Graphics.MeasureString(shortcuttext, SystemInformation.MenuFont).Width);
			textwidth += shortcuttextwidth;
			e.ItemHeight = 22;
			
			if (Parent == Parent.GetMainMenu())
				e.ItemWidth  = textwidth - 5;
			else
				e.ItemWidth   = Math.Max(160, textwidth + 15);
		}
		
		protected override void OnSelect(EventArgs e)
		{
			base.OnSelect(e);
		}
		
		protected override void OnDrawItem(DrawItemEventArgs e)
		{
			base.OnDrawItem(e);
			Graphics  g      = e.Graphics;
			Rectangle bounds = e.Bounds;
			bool selected = (e.State & DrawItemState.Selected) > 0;
			bool toplevel = (Parent == Parent.GetMainMenu());
			bool hasicon  = Icon != null;
			
			DrawBackground(g, bounds, e.State, toplevel, hasicon);
			
			if (hasicon) {
				DrawIcon(g, Icon, bounds, selected, Enabled, Checked);
			} else if (Checked) {
				DrawCheckmark(g, bounds, selected);
			}
			
			if (Text == "-") {
				DrawSeparator(g, bounds);
			} else {
				DrawMenuText(g, bounds, Text, shortcuttext, Enabled, toplevel, e.State);
			}
		}
		
		// drawing routines
		
		public void DrawCheckmark(Graphics g, Rectangle bounds, bool selected)
		{
			ControlPaint.DrawMenuGlyph(g, new Rectangle(bounds.X + 2, bounds.Y + 2, 14, 14), MenuGlyph.Checkmark);
			g.DrawRectangle(new Pen(Style.BorderColor), bounds.X + 1, bounds.Y + 1, 14 + 1, 14 + 1);
		}
		
		public void DrawIcon(Graphics g, Image icon, Rectangle bounds, bool selected, bool enabled, bool ischecked)
		{
			if (enabled) {
				if (selected) {
					ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 2, Color.Black);
					g.DrawImage(icon, bounds.Left + 4, bounds.Top + 3, icon.Width, icon.Height);
				} else {
					g.DrawImage(icon, bounds.Left + 3, bounds.Top + 2, icon.Width, icon.Height);
				}
			} else {
				ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 2, SystemColors.HighlightText);
			}
		}
		
		public void DrawSeparator(Graphics g, Rectangle bounds)
		{
			int y = bounds.Y + bounds.Height / 2;
			g.DrawLine(new Pen(SystemColors.ControlDark), bounds.X + SystemInformation.SmallIconSize.Width + 7, y, bounds.X + bounds.Width - 2, y);
		}
		
		public void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state, bool toplevel, bool hasicon)
		{
			bool selected = (state & DrawItemState.Selected) > 0;
			
			if (selected || ((state & DrawItemState.HotLight) > 0)) {
				if (toplevel && selected) {
					g.FillRectangle(new SolidBrush(ibgcolor), bounds);
					ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, Border3DStyle.Flat, Border3DSide.Top | Border3DSide.Left | Border3DSide.Right);
				} else {
					g.FillRectangle(new SolidBrush(Style.BackColor), bounds);
					g.DrawRectangle(new Pen(Style.BorderColor), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
				}
			} else {
				if (!toplevel) {
					g.FillRectangle(new SolidBrush(ibgcolor), bounds);
					bounds.X += 16 + 5;
					bounds.Width -= 16 + 5;
					g.FillRectangle(new SolidBrush(bgcolor), bounds);
				} else {
					g.FillRectangle(SystemBrushes.Control, bounds);
					
				}
			}
		}
		
		public void DrawMenuText(Graphics g, Rectangle bounds, string text, string shortcut, bool enabled, bool toplevel, DrawItemState state)
		{
			StringFormat stringformat = new StringFormat();
			stringformat.HotkeyPrefix = ((state & DrawItemState.NoAccelerator) > 0) ? HotkeyPrefix.Hide : HotkeyPrefix.Show;
			int textwidth = (int)(g.MeasureString(text, SystemInformation.MenuFont).Width);
			int shortcutwidth = (int)(g.MeasureString(shortcut, SystemInformation.MenuFont).Width);
			
			int x = toplevel ? bounds.Left + (bounds.Width - textwidth) / 2: bounds.Left + TEXTSTART;
			int y = bounds.Top + 2;
			
			if(! toplevel) {
				y += 2;
			}
			
			Brush brush = null;
			if (!enabled)
				brush = new SolidBrush(Color.FromArgb(120, SystemColors.MenuText));
			else
				brush = new SolidBrush(SystemColors.MenuText);
			g.DrawString(text, SystemInformation.MenuFont, brush, x, y, stringformat);
			
			g.DrawString(shortcut, SystemInformation.MenuFont, brush, bounds.Right - shortcutwidth - 10, bounds.Top + 2, stringformat);
		}
	}
}
